#ifndef DATABASE_DATA_HOLDER_H
#define DATABASE_DATA_HOLDER_H

#include <shared_mutex>
#include <string>

#include <sqlite_modern_cpp.h>

#include "data_elements/data_element.h"

namespace Database
{

class DataGate
{
public:
    explicit DataGate(const std::string& databaseFilename = "");
    virtual ~DataGate() = default;

    bool saveElement(DataElementPtr dataElement) const;
    bool saveElement(Elements::ElementPtr element) const;

    DataElementPtr loadElement(
        Elements::ElementType elementType,
        unsigned id
    ) const;

    DataElements loadElements(
        Elements::ElementType elementType,
        std::vector<unsigned> ids = {}
    ) const;

    template <typename Function, typename... Args>
    std::vector<unsigned> getElementsIds(
        Function function,
        Args&&... args
    ) const
    {
        return function(*m_database, std::forward<Args>(args)...);
    }

    template <typename Function, typename... Args>
    void remove(
        Function function,
        Args&&... args
    ) const
    {
        return function(*m_database, std::forward<Args>(args)...);
    }

protected:
    mutable std::shared_mutex m_lock;
    std::unique_ptr<sqlite::database> m_database;
};

} // namespace Database

#endif // DATABASE_DATA_HOLDER_H
